import { Server } from 'socket.io'
import { Scheduler } from '../utils/scheduler'
import { db_init } from '../utils/db_init'
import { nanoid } from 'nanoid'
import { SocketPort } from '../../config.json'

const db = useDatabase()
db_init()

export default defineNitroPlugin((nitroApp) => {
    const io = new Server(SocketPort, {
        cors: {
            origin: '*',
            methods: ['GET', 'POST']
        }
    })

    const S = new Scheduler()
    S.init()

    io.on('connection', (socket) => {
        console.log(`[ ${socket.id} ]已连接`,);
        socket.on('getTaskList', () => {
            socket.emit('getTaskList', S.getTaskList())
        })

        socket.on('addTask', async (data) => {
            const { name, cron, webhook, secret, template_id, template_variables, status } = data
            const id = nanoid(8)
            try {
                S.addTask({ id, name, cron, webhook, secret, template_id, template_variables, status })
                await db.sql`
                INSERT INTO [task-list] ("id","name", "cron", "webhook", "secret", "template_id","template_variables","status")
                VALUES (${id},${name}, ${cron}, ${webhook}, ${secret}, ${template_id},${JSON.stringify(template_variables)},${status})`
                socket.emit('addTask', { message: '添加成功', type: 'success' })
            } catch (error: any) {
                console.log(error.message);
                socket.emit('addTask', { message: `添加失败:${error.message}`, type: 'error' })
            }
        })

        socket.on('deleteTask', async (data) => {
            const { id, name } = data
            try {
                S.removeTask(id)
                await db.sql`
                DELETE FROM [task-list]
                WHERE "id"=${id} AND "name"=${name}`
                socket.emit('deleteTask', { message: '删除成功', type: 'success' })
            } catch (error: any) {
                console.log(error.message);
                socket.emit('deleteTask', { message: `删除失败:${error.message}`, type: 'error' })
            }
        })

        socket.on('changeTaskStatus', async (data) => {
            const { id, name, status } = data
            if (status === 1) {
                try {
                    S.startTask(id)
                    const taskActiveStatus = S.getTaskActiveStatus(id)
                    await db.sql`
                        UPDATE [task-list]
                        SET "status"=${taskActiveStatus ? 1 : 0} 
                        WHERE "id"=${id} AND "name"=${name}`
                    socket.emit('changeTaskStatus', { message: '开启成功', type: 'success' })
                } catch (error: any) {
                    console.log(error.message);
                    socket.emit('changeTaskStatus', { message: `开启失败:${error.message}`, type: 'error' })
                }
            } else {
                try {
                    S.stopTask(id)
                    const taskActiveStatus = S.getTaskActiveStatus(id)
                    await db.sql`
                        UPDATE [task-list]
                        SET "status"=${taskActiveStatus ? 1 : 0} 
                        WHERE "id"=${id} AND "name"=${name}`
                    socket.emit('changeTaskStatus', { message: '停止成功', type: 'success' })
                } catch (error: any) {
                    console.log(error.message);
                    socket.emit('changeTaskStatus', { message: `停止失败:${error.message}`, type: 'error' })
                }

            }

        })

        socket.on('viewNextDates', async (data) => {
            const { id, count } = data
            let nextDates = S.getTaskNextDates(id, count)
            nextDates = nextDates.map((item: any) => {
                return new Date(item.ts).toLocaleString()
            })
            socket.emit('viewNextDates', { nextDates })
        })

        socket.on('disconnect', () => {
            console.log(`[ ${socket.id} ]已断开连接`,);
        });

        const getVariableList = async () => {
            try {
                const { rows } = await db.sql`
                SELECT * FROM [variable-list]`
                return rows
            } catch (error: any) {
                console.log(error.message);
                return []
            }
        }

        socket.on('getVariableList', async () => {
            socket.emit('getVariableList', await getVariableList())
        })

        socket.on('addVariable', async (data) => {
            const { name, content } = data
            const id = nanoid(8)
            try {
                await db.sql`
                INSERT INTO [variable-list] ("id","name","content")
                VALUES (${id},${name},${content})`
                socket.emit('addVariable', { message: '添加成功', type: 'success' })
            } catch (error: any) {
                console.log(error.message);
                socket.emit('addVariable', { message: `添加失败:${error.message}`, type: 'error' })
            }
        })

        socket.on('deleteVariable', async (data) => {
            const { id, name } = data
            try {
                await db.sql`
                DELETE FROM [variable-list]
                WHERE "id"=${id} AND "name"=${name}`
                socket.emit('deleteVariable', { message: '删除成功', type: 'success' })
            } catch (error: any) {
                console.log(error.message);
                socket.emit('deleteVariable', { message: `删除失败:${error.message}`, type: 'error' })
            }
        })

        socket.on('execute', async (url) => {
            try {
                const result = await post(url)
                socket.emit('execute', JSON.stringify(result, null, 4))
            } catch (error: any) {
                console.log(error.message);
                socket.emit('execute', error.message)
            }
        })

        socket.on('runTask', async (data) => {
            const { id } = data
            try {
                S.runTask(id)
                socket.emit('runTask', { message: '执行成功', type: 'success' })
            } catch (error: any) {
                console.log(error.message);
                socket.emit('runTask', { message: `执行失败:${error.message}`, type: 'error' })
            }
        })

        socket.on('updateTask', async (data) => {
            const { id, name, cron, template_id, template_variables, status } = data
            try {
                S.updateTask(data)
                await db.sql`
                        UPDATE [task-list]
                        SET "name"=${name},"cron"=${cron},"template_id"=${template_id},"template_variables"=${JSON.stringify(template_variables)},"status"=${status}
                        WHERE "id"=${id}`
                socket.emit('runTask', { message: '更新成功', type: 'success' })
            } catch (error: any) {
                console.log(error.message);
                socket.emit('runTask', { message: `更新失败:${error.message}`, type: 'error' })
            }
        })

        const getCronTimeList = async () => {
            try {
                const { rows } = await db.sql`
                SELECT * FROM [crontime-list]`
                return rows
            } catch (error: any) {
                console.log(error.message);
                return []
            }
        }

        socket.on('getCronTimeList', async () => {
            socket.emit('getCronTimeList', await getCronTimeList())
        })

        socket.on('addCronTime', async (data) => {
            const { name, cron } = data
            const id = nanoid(8)
            try {
                await db.sql`
                INSERT INTO [crontime-list] ("id","name","cron")
                VALUES (${id},${name},${cron})`
                socket.emit('addCronTime', { message: '添加成功', type: 'success' })
            } catch (error: any) {
                console.log(error.message);
                socket.emit('addCronTime', { message: `添加失败:${error.message}`, type: 'error' })
            }
        })

        socket.on('updateCronTime', async (data) => {
            const { id, name, cron } = data
            try {
                await db.sql`
                        UPDATE [crontime-list]
                        SET "name"=${name},"cron"=${cron}
                        WHERE "id"=${id}`
                socket.emit('updateCronTime', { message: '更新成功', type: 'success' })
            } catch (error: any) {
                console.log(error.message);
                socket.emit('updateCronTime', { message: `更新失败:${error.message}`, type: 'error' })
            }
        })

        socket.on('deleteCronTime', async (data) => {
            const { id, name } = data
            try {
                await db.sql`
                DELETE FROM [crontime-list]
                WHERE "id"=${id} AND "name"=${name}`
                socket.emit('deleteCronTime', { message: '删除成功', type: 'success' })
            } catch (error: any) {
                console.log(error.message);
                socket.emit('deleteCronTime', { message: `删除失败:${error.message}`, type: 'error' })
            }
        })
    })
})